home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / archivrs / general / lhasrc.exe / SFX_.ASM < prev    next >
Assembly Source File  |  1991-03-03  |  24KB  |  1,303 lines

  1. ;***********************************************
  2. ;    sfx_.asm -- self-extract module
  3. ;***********************************************
  4.  
  5. page    0, 128
  6. include    amscls.inc
  7.  
  8. $_init GEN
  9.  
  10. _TEXT    segment byte public 'CODE'
  11. _TEXT    ends
  12.  
  13. DGROUP    group    _BSS
  14.         assume    cs:_TEXT, ds:DGROUP
  15.  
  16. CRC16            equ        0a001h
  17. BufSiz            equ        04000h
  18.  
  19. NC            =        (200h - 2)
  20. NP            =        14
  21. NT            =        19
  22. NPT            =        080h
  23.  
  24. CBIT        =        9
  25. PBIT        =        4
  26. TBIT        =        5
  27.  
  28. DSIZ        =        2000h
  29. DSIZ2        =        DSIZ * 2
  30.  
  31. LzHead    struc
  32.         HeadSiz db        ?
  33.         HeadChk db        ?
  34.         HeadID    db        3 dup (?)
  35.         Method    db        ?
  36.                 db        ?
  37.         PacSiz    dw        2 dup (?)
  38.         OrgSiz    dw        2 dup (?)
  39.         FTime    dw        ?
  40.         FDate    dw        ?
  41.         FAttr    dw        ?
  42.         FnLen    db        ?
  43.         Fname    db        80h dup (?)
  44. LzHead    ends
  45.  
  46. _BSS    segment para public 'BSS'
  47.         public    crctbl
  48.         public    cpyhdr, infile, outfile
  49.         public    inpptr, inpbuf, text_
  50.         public    curcrc, orgcrc
  51.         public    myname
  52.         public    pathname, fnnext, swchar
  53.         public    blocksize_
  54.  
  55. text_            db        DSIZ2 dup (?)
  56. inpbuf            db        BufSiz dup (?)
  57. crctbl            dw        100h dup (?)
  58. cpyhdr            LzHead    1 dup (<?>)
  59. inpptr            dw        1 dup (?)
  60. infile            dw        1 dup (?)
  61. outfile            dw        1 dup (?)
  62. orgcrc            dw        1 dup (?)
  63. curcrc            dw        1 dup (?)
  64. blocksize_        dw        1 dup (?)
  65.  
  66. len_cnt            dw        17 dup (?)
  67. start            dw        17 dup (?)
  68. weight            dw        17 dup (?)
  69.  
  70. public    len_cnt
  71. public    start
  72. public    weight
  73.  
  74.  
  75. left_            dw        2 * NC - 1 dup (?)
  76. right_            dw        2 * NC - 1 dup (?)
  77.  
  78. c_table_        dw        4096 dup (?)
  79. pt_table_        dw        256 dup (?)
  80. c_len_            db        NC dup (?)
  81. pt_len_            db        NPT dup (?)
  82.  
  83. public    left_
  84. public    right_
  85. public    c_table_
  86. public    pt_table_
  87. public    c_len_
  88. public    pt_len_
  89.  
  90. bitbuf_            dw        1 dup (?)
  91. subbitbuf_        db        1 dup (?)
  92. bitcount_        db        1 dup (?)
  93.  
  94. myname            db        80h dup (?)
  95. pathname        db        80h dup (?)
  96. fnnext            dw        1 dup (?)
  97. fnptr            dw        1 dup (?)
  98. swchar            db        1 dup (?)
  99. endBBS            label    byte
  100. _BSS            ends
  101.  
  102. _TEXT    segment byte public 'CODE'
  103.         assume    cs:_TEXT
  104.  
  105.         org        0100h
  106.  
  107.         public    start, main
  108.         public    BSSseg
  109.         public    #cright, crlf, space
  110.         public    absent, #myself, broken, extend
  111.         public    #subver
  112.  
  113. top:
  114.         jmp        main
  115.  
  116. BSSseg    =        (#endofcode - top + 10fh) / 10h
  117. mes_yn    equ        space - 1
  118. space    db        ' ', 0
  119. #cright    db        "LHA's SFX 2.11"
  120. #subver    db        "L (c) Yoshi, 1991"
  121. crlf    db        13, 10, 0
  122. absent    db        'Rename to '
  123. #myself    db        'FILENAME.EXT', 0
  124. overwt    db        'Overwrite ', 0
  125. yesno    db        '[Y/N] ', 0
  126. broken    db        'Broken file ', 0
  127. write    db        'Write', 0
  128. header    db        'Header', 0
  129. crcmes    db        'CRC'
  130. error    db        ' Error', 0
  131. auto    db        1, '!'
  132. autoflg db        '.' shr 1
  133.         db        'BAT'
  134. extend    db        0ffh
  135. attrib    db        0
  136.  
  137. envseg    =        002ch
  138. cmdcnt    =        0080h
  139. cmdline =        0081h
  140.  
  141. ;-----------------------------------------------
  142. ;        âüâCâôâïü[â`âô
  143. ;-----------------------------------------------
  144. main:
  145.         cld
  146.         mov        sp, offset top
  147.         mov        ax, cs
  148.         add        ax, BSSseg
  149.         mov        es, ax
  150.  
  151.         assume    es:DGROUP
  152.  
  153.         call    @getopt
  154.  
  155.         public    #getopt
  156. #getopt:
  157.         mov        bx, offset #cright
  158.         call    mesout
  159.         push    es
  160.         pop        ds
  161.  
  162.         assume    ds:DGROUP
  163. ;-----------------------------------------------
  164. ;        Get my name
  165. ;-----------------------------------------------
  166.         mov        ah, 30h
  167.         int        21h                                ; get DOS ver.
  168.         mov        bx, ax
  169.         push    ds
  170.         $_if <cmp al, 3>, AE                    ; if DOS ver. >= 3.00
  171.             mov        es, ss:[envseg]
  172.             xor        ax, ax
  173.             mov        di, ax
  174.             mov        cx, -1
  175.             $_do
  176.                 repne    scasb
  177.                 scasb
  178.             $_until , E
  179.             inc        ax
  180.             scasw
  181.             push    es
  182.             pop        ds
  183.             mov        dx, di
  184.             $_if , E
  185.                 call    openme
  186.             $_endif
  187.         $_endif
  188. brknenv:
  189.         push    cs
  190.         pop        ds
  191.         mov        dx, offset #myself
  192.         call    openme
  193.         $_if <cmp bl, 2>, E                    ; if DOS ver. = 2
  194.             mov        ax, ss:[0002h]            ;  get pathname from trash
  195.             sub        ax, 38h                    ;  of command.com
  196.             mov        ds, ax
  197.             mov        dx, 0009h
  198.             call    openme
  199.         $_endif
  200.         mov        bx, offset absent
  201.         jmp        errout1
  202. openme:
  203.         mov        ax, 3d00h
  204.         int        21h                                ; Open Myself
  205.         $_if , C
  206.             ret
  207.         $_endif
  208.         pop        cx                                ; pop old ip
  209.  
  210.         pop        ds
  211.         mov        infile, ax
  212.  
  213.         mov        bx, ax
  214.         xor        cx, cx
  215.  
  216. ifndef COM
  217.     exehdr    =        20h
  218. else
  219.     exehdr    =        0h
  220. endif
  221.  
  222.         mov        dx, (#endofcode - top) + exehdr
  223.  
  224.         public    #seeksize
  225. #seeksize:
  226.  
  227.         mov        ax, 4200h
  228.         int        21h                                ; Move a File Pointer
  229.         $_if , C
  230. brokenerr:
  231.             mov        bx, offset broken        ; Broken file
  232.             jmp        errout
  233.         $_endif
  234.         push    ds
  235.         pop        es
  236. ;---------------------------------------
  237. ;        make CRC table
  238. ;---------------------------------------
  239.         mov        di, offset crctbl
  240.         xor        dx, dx
  241.         $_do
  242.             mov        ax, dx
  243.             mov        cx, 8
  244.             $_do
  245.                 $_if <shr ax, 1>, C
  246.                     xor        ax, CRC16
  247.                 $_endif
  248.             $_until <LOOP>
  249.             stosw
  250.         $_until <inc dl>, Z
  251. ;---------------------------------------
  252.  
  253.         public mainloop
  254. mainloop:
  255.         $_while <TRUE>
  256.  
  257.             call    crlfout
  258. ; Get Header ---------------------------
  259.             mov        si, offset DGROUP:cpyhdr.HeadSiz
  260.             mov        dx, si
  261.             mov        cx, 1
  262.             mov        [si], ch
  263.             mov        bx, infile
  264.             mov        ah, 3fh
  265.             int        21h                        ; Read header size
  266.             dec        cx                        ; cx = 0
  267.             add        cl, [si]
  268.             $_if , Z
  269.                 jmp        exit
  270.             $_endif
  271.             inc        dx
  272.             inc        si
  273.  
  274.             inc        cx
  275.             mov        ah, 3fh
  276.             int        21h                        ; Read header
  277.  
  278. ; Test Header Sum ----------------------
  279.             lodsb
  280.             push    si                    ; cpyhdr.HeadID
  281.             dec        cx
  282.             dec        si
  283.             $_do
  284.                 inc        si
  285.                 sub        al, [si]
  286.             $_until <LOOP>
  287.             jne        errhdr
  288.             pop        si
  289.  
  290. ; Test Header ID -----------------------
  291.             lodsw
  292.             $_if <cmp ax, 'l-'>, NE, OR
  293.                 lodsw
  294.                 xchg    al, ah
  295.                 sub        ax, 'h0'
  296.                 mov        bp, ax                ; bp = method
  297.             $_c                 , NZ, AND
  298.             $_c  <sub ax, 0004h>, NE, AND
  299.             $_c  <dec ax>       , NE, OR
  300.                 lodsb
  301.             $_c  <sub al, '-'>, NZ
  302. errhdr:
  303.                 mov        bx, offset header
  304.                 jmp        errout
  305.             $_endif
  306.  
  307. ; Get original CRC ---------------------
  308.             mov        bx, offset DGROUP:cpyhdr.Fname
  309.             mov        dx, bx
  310.             mov        cx, [bx - 1]
  311.             add        bl, cl                ; doesn't carry up
  312.  
  313.             xchg    ax, [bx]            ; ax = 0, [bx] = CRC
  314.             mov        orgcrc, ax
  315.  
  316. ; Test Special File ? ------------------
  317.             mov        fnptr, dx
  318.             cmp        cx, 2101h                ; 01h, '!'
  319.             $_if , E
  320.                 mov        ax, 1
  321.                 jmp        mn7
  322.             $_endif
  323.  
  324.             call    @extended
  325.  
  326.         public    #extended
  327. #extended:
  328.  
  329.  
  330. ; Display File name --------------------
  331.             mov        word ptr [bx], 0 * 256 + ' '
  332.             mov        bx, dx
  333.             call    disp                    ; output file name
  334.             mov        byte ptr [bx - 1], 0
  335.  
  336.             jcxz    mn9                        ; !.BAT ?
  337.  
  338. ; Check Existence of File --------------
  339.             mov        ax, 4300h                ; get file attr
  340.             int        21h                        ;    (for MS-DOS 3.3)
  341.             jc        mn1
  342.  
  343. ; Overwrite ? --------------------------
  344.             mov        bx, offset overwt    ; prompt
  345.             call    mesout
  346.             call    getyn
  347.             je        mn1
  348.  
  349. ; Skip to next File --------------------
  350.             mov        dx, DGROUP:cpyhdr.PacSiz        ; skip file
  351.             mov        cx, DGROUP:cpyhdr.PacSiz + 2
  352.  
  353.             mov        bx, infile
  354.             mov        ax, 4201h
  355.             int        21h                    ; Move a File Pointer
  356.             jmp        mn6
  357. mn9:
  358.             mov        cs:autoflg, 0dh
  359.  
  360. ; Create a New File --------------------
  361. mn1:
  362.             mov        cx, 0020h
  363.             mov        ah, 3ch
  364.             int        21h                    ; Create a File
  365.             $_if , C
  366.                 jmp        errwrite
  367.             $_endif
  368.  
  369. ; Decode -------------------------------
  370. mn7:
  371.             mov        outfile, ax
  372.  
  373.             xor        ax, ax
  374.             mov        curcrc, ax
  375.             dec        ax
  376.             mov        inpptr, ax
  377.  
  378.             push    dx
  379.             $_if <or bp, bp>, NZ
  380.                 call    decode
  381.             $_else
  382.                 call    copyall
  383.             $_endif
  384.             pop        si
  385.  
  386. ; Set Time-Stamp -----------------------
  387.             mov        bx, outfile
  388.             cmp        bx, 1                    ; file '!' ?
  389.             je        mn8
  390.  
  391.             mov        dx, DGROUP:cpyhdr.FDate
  392.             mov        cx, DGROUP:cpyhdr.FTime
  393.             mov        ax, 5701h                ; set date
  394.             int        21h
  395.             call    close
  396.  
  397. ; Check CRC ----------------------------
  398.             mov        ax, curcrc
  399.             cmp        ax, orgcrc
  400.             jne        errcrc
  401.  
  402.             call    @setattr
  403.  
  404. public    #setattr
  405. #setattr:
  406.  
  407.  
  408.             jmp        mn6
  409. mn8:
  410.             call    getyn
  411.             jne        exit1
  412. mn6:
  413.         $_enddo
  414.         mov        bx, infile
  415.         call    close
  416.  
  417.         public    exit
  418. exit:
  419.         call    @autoexec
  420.  
  421.         public    #autoexec
  422. #autoexec:
  423. exit1:
  424.         xor        al, al
  425. exit2:
  426.         mov        ah, 4ch
  427.         int        21h
  428.  
  429. ;-----------------------------------------------
  430. ;        âGâëü[Åêù¥
  431. ;-----------------------------------------------
  432.         public    errhdr, errwrite, errout
  433. errcrc:
  434.         call    unlink
  435.         mov        bx, offset crcmes
  436.         jmp        short errout1
  437.  
  438. errwrite:
  439.         mov        bx, outfile
  440.         call    close
  441.         call    unlink
  442.         mov        bx, offset write
  443.  
  444. errout:
  445.         call    mesout
  446.         mov        bx, offset error
  447. errout1:
  448.         call    mesout
  449.         mov        al, 1
  450.         jmp        exit2
  451.  
  452. ;-----------------------------------------------
  453. ;        get 'Y' or 'N'
  454. ;-----------------------------------------------
  455.         public    getyn
  456. getyn    proc    near
  457.         mov        bx, offset yesno                ; prompt
  458.         call    mesout
  459.         $_do
  460.             mov        ah, 08h
  461.             int        21h
  462.             and        al, 0dfh
  463.         $_until <cmp al, 'Y'>, E, OR
  464.         $_c        <cmp al, 'N'>, E
  465.         mov        bx, offset mes_yn
  466.         mov        cs:[bx], al
  467.         call    mesout
  468.         cmp        al, 'Y'
  469.         ret
  470. getyn    endp
  471.  
  472. ;-----------------------------------------------
  473. ;        âoâbâtâ@é╠Åoù═
  474. ;-----------------------------------------------
  475.         public    putbuf
  476.         public    putbuf2
  477. putbuf    proc    near
  478.     xor        dx, dx    ;    mov        dx, offset DGROUP:text_
  479.     mov        cx, di
  480.     sub        cx, dx
  481. putbuf2:
  482.     jcxz    return
  483.     mov        bx, outfile
  484.     mov        ah, 40h
  485.     int        21h
  486.     $_if <sub ax, cx>, NE
  487.         cmp        bx, 1
  488.         jne        errwrite
  489.     $_endif
  490. calccrc:
  491.     mov        si, dx
  492.     mov        bx, curcrc
  493. ;    xor        ah, ah                        ; ah = 0
  494. ;    cld
  495.     $_do
  496.         lodsb
  497.         xor        bl, al
  498.         mov        al, bh
  499.         mov        bh, ah
  500.         shl        bx, 1
  501.         mov        bx, crctbl[bx]
  502.         xor        bx, ax
  503.     $_until <LOOP>
  504.     mov        curcrc, bx
  505.     mov        di, dx
  506.  
  507.     cmp        outfile, 1
  508.     je        return
  509.     mov        ah, 02h
  510.     mov        dl, '.'
  511.     jmp        short int21_ret                    ; int    21h
  512.                                             ; ret
  513. putbuf    endp
  514.  
  515. ;-----------------------------------------------
  516. ;        é╗é╠é▄é▄Åoù═
  517. ;-----------------------------------------------
  518.         public    copyall
  519. copyall proc    near
  520.         xor        di, di
  521.         $_while <TRUE>
  522.                 mov        bx, offset DGROUP:cpyhdr.OrgSiz
  523.                 sub        [bx], di
  524.                 sbb        word ptr 2[bx], 0
  525.                 mov        cx, DSIZ2
  526.                 $_if , Z, AND
  527.                         mov        ax, [bx]
  528.                         or        ax, ax
  529.                         jz        cpyend
  530.                 $_c     <cmp ax, cx>, B
  531.                         mov        cx, ax
  532.                 $_endif
  533.  
  534.                 xor        dx, dx    ;    mov        dx, offset DGROUP:text_
  535.                 mov        bx, infile
  536.                 mov        ah, 3fh
  537.                 int        21h
  538.                 push    cx
  539.                 call    putbuf2
  540.                 pop        di
  541.         $_enddo
  542. cpyend:
  543.         ret
  544. copyall endp
  545.  
  546. ;-----------------------------------------------
  547. ;        âtâ@âCâïé╠ close
  548. ;-----------------------------------------------
  549.         public    close
  550. close    proc    near
  551.         mov        ah, 3eh
  552.         jmp        short int21_ret                    ; int    21h
  553.                                                 ; ret
  554. close    endp
  555.  
  556. ;-----------------------------------------------
  557. ;        âtâ@âCâïé╠ìφÅ£
  558. ;-----------------------------------------------
  559.         public    unlink
  560. unlink    proc    near
  561.         mov        dx, fnptr
  562.         mov        ah, 41h                            ; unlink
  563. int21_ret:
  564.         int        21h
  565. return:
  566.         ret
  567. unlink    endp
  568.  
  569. ;-----------------------------------------------
  570. ;        CR, LF é╠Åoù═
  571. ;-----------------------------------------------
  572. crlfout    proc    near
  573.         mov        bx, offset crlf
  574. crlfout    endp
  575. ;-----------------------------------------------
  576. ;        âüâbâZü[âWé╠Åoù═
  577. ;-----------------------------------------------
  578.         public    mesout
  579. mesout    proc    near
  580.         push    ds
  581.         push    cs
  582.         pop        ds
  583.         call    disp
  584.         pop        ds
  585.         ret
  586. mesout    endp
  587.  
  588. ;-----------------------------------------------
  589. ;        display ASCIZ char
  590. ;-----------------------------------------------
  591.         public    disp
  592. disp    proc    near
  593.         push    ax
  594.         push    dx
  595.         $_do
  596.             mov        dl, [bx]
  597.             inc        bx
  598.             mov        ah, 02h
  599.             int        21h
  600.         $_until <cmp byte ptr [bx], 0>, E
  601.         pop        dx
  602.         pop        ax
  603.         ret
  604. disp    endp
  605.  
  606. ;-----------------------------------------------
  607. ;        getc
  608. ;            ax: 1 byte (return)
  609. ;-----------------------------------------------
  610.         public    getc
  611. getc    proc    near
  612.         mov        bx, inpptr
  613.         $_if <cmp bx, offset inpbuf + BufSiz>, AE
  614.     ;-----------------------------------------------
  615.     ;        buffer ôⁿù═
  616.     ;-----------------------------------------------
  617.             public    getbuf
  618.     getbuf    proc    near
  619.             push    cx
  620.             push    dx
  621.             mov        dx, offset DGROUP:inpbuf
  622.             mov        cx, BufSiz
  623.             mov        bx, offset DGROUP:cpyhdr.PacSiz
  624.             sub        [bx], cx
  625.             sbb        word ptr 2[bx], 0
  626.             $_if , C
  627.                 add        cx, [bx]
  628.             $_endif
  629.             mov        bx, infile
  630.             mov        ah, 3fh
  631.             int        21h                    ; Read from an Archive
  632.             mov        bx, dx
  633.             pop        dx
  634.             pop        cx
  635.     getbuf    endp
  636.     ;-----------------------------------------------
  637.         $_endif
  638.         mov        al, [bx]
  639.         inc        bx
  640.         mov        inpptr, bx
  641.         ret
  642. getc    endp
  643.  
  644. ;-----------------------------------------------
  645. ;        extract routines
  646. ;-----------------------------------------------
  647.         public    decode
  648. decode proc    near
  649.     xor        ax, ax
  650.     mov        blocksize_, ax
  651.     mov        bitbuf_, ax
  652.     mov        subbitbuf_, al
  653.     mov        bitcount_, al
  654.  
  655.     mov        al,16
  656.     call    fillbuf_
  657.  
  658.     xor        di, di    ;    mov        di, offset DGROUP:text_
  659.     jmp        $entry
  660.  
  661. $loop:
  662.         call    decode_c_st1_
  663.         $_if <or ah, ah>, Z
  664.             stosb
  665.             $_if <cmp di, offset DGROUP:text_[DSIZ2]>, E
  666.                 call    putbuf
  667.             $_endif
  668. $entry:
  669.             sub        word ptr cpyhdr.OrgSiz, 1
  670.             jnc        $loop
  671.         $_else
  672.             mov        cx, ax
  673.             sub        cx, 100h - 3
  674.             call    decode_p_st1_
  675.             mov        si, di
  676.             stc
  677.             sbb        si, ax
  678.             push    cx
  679.             $_do
  680.                 and        si, DSIZ2 - 1
  681.                 movsb
  682.                 test    di, DSIZ2
  683.                 $_if , NZ
  684.                     push    cx
  685.                     push    si
  686.                     call    putbuf
  687.                     pop        si
  688.                     pop        cx
  689.                 $_endif
  690.             $_until <LOOP>
  691.             pop        cx
  692.             sub        word ptr cpyhdr.OrgSiz, cx
  693.             jnc        $loop
  694.         $_endif
  695.         sbb        word ptr cpyhdr.OrgSiz + 2, 0
  696.         jnc        $loop
  697.     $endloop:
  698.     jmp        putbuf
  699. decode endp
  700.  
  701.  
  702. ;    static void read_pt_len(short nn, short nbit, short i_special)
  703. ;public    read_pt_len_
  704. read_pt_len_    proc    near
  705.     push    si
  706.     mov        al, dl
  707.     call    getbits_
  708.     $_if <cmp ax, si>, A
  709.         jmp        brokenerr
  710.     $_endif
  711.     mov        di, offset DGROUP:pt_len_
  712.     $_if <or ax, ax>, Z
  713.         pop        cx
  714.         rep        stosb
  715.         mov        al, dl
  716.         call    getbits_
  717.         mov        cx, 256
  718.         mov        di, offset DGROUP:pt_table_
  719.         rep        stosw
  720.         ret
  721.     $_else
  722.         mov        dx, cx            ; dl = i_special
  723.         add        dx, di
  724.         mov        si, di
  725.         add        si, ax            ; ax = n
  726.         $_do
  727.             mov        al, 3
  728.             call    getbits_
  729.             $_if <cmp al, 7>, E
  730.                 mov        bx, bitbuf_
  731.                 $_while <shl bx, 1>, C
  732.                     inc        ax
  733.                 $_enddo
  734.                 push    ax
  735.                 sub        al, 6
  736.                 call    fillbuf_
  737.                 pop        ax
  738.             $_endif
  739.             stosb
  740.             $_if <cmp di, dx>, E
  741.                 mov        al, 2
  742.                 call    getbits_
  743.                 mov        cx, ax
  744.                 xor        al, al
  745.                 rep        stosb
  746.             $_endif
  747.         $_until <cmp di, si>, AE
  748.         pop        si                        ; nn
  749.         mov        bp, offset DGROUP:pt_len_
  750.         lea        cx, [bp + si]    ;    lea        cx, DGROUP:pt_len_[si]
  751.         sub        cx, di
  752.         xor        al, al
  753.         rep        stosb
  754.         mov        ax, si
  755.         mov        cx, 8
  756.         mov        di, offset DGROUP:pt_table_
  757.         jmp        make_table_
  758.     $_endif
  759. read_pt_len_    endp
  760.  
  761. ;    static void read_c_len(void)
  762. ;public    read_c_len_
  763. read_c_len_    proc    near
  764.     mov        al, CBIT
  765.     call    getbits_
  766.     $_if <cmp ax, NC>, A
  767.         jmp        brokenerr
  768.     $_endif
  769.     mov        di, offset DGROUP:c_len_
  770.     $_if <or ax, ax>, Z
  771.         mov        cx, NC
  772.         rep        stosb
  773.         mov        al, CBIT
  774.         call    getbits_
  775.         mov        cx, 4096
  776.         mov        di, offset DGROUP:c_table_
  777.         rep        stosw
  778.         ret
  779.     $_else
  780.         mov        dx, di
  781.         add        dx, ax            ; ax = n
  782.         push    di
  783.         $_do
  784.             mov        ax, bitbuf_
  785.             mov        bl, ah
  786.             xor        bh, bh
  787.             shl        bx, 1
  788.             mov        bx, pt_table_[bx]
  789.  
  790.             mov        si, offset read_c_len_1
  791.             mov        cx, NT
  792.             jmp        tree1
  793.  
  794. if 0
  795.             $_while <cmp bx, NT>, AE
  796.                 $_if <shl al, 1>, C
  797.                     mov        bx, right_[bx]
  798.                 $_else
  799.                     mov        bx, left_[bx]
  800.                 $_endif
  801.             $_enddo
  802. endif
  803.  
  804. read_c_len_1:
  805.             push    bx
  806.             mov        al, pt_len_[bx]
  807.             call    fillbuf_
  808.             pop        ax
  809.             $_if <sub ax, 2>, BE
  810.                 $_if , Z
  811.                     mov        al, CBIT
  812.                     call    getbits_
  813.                     add        ax, 20
  814.                     mov        cx, ax
  815.                 $_else
  816.                     $_if <inc ax>, Z
  817.                         mov        al, 4
  818.                         call    getbits_
  819.                         add        ax, 3
  820.                         mov        cx, ax
  821.                     $_else
  822.                         mov        cx, 1
  823.                     $_endif
  824.                 $_endif
  825.                 xor        al, al
  826.                 rep        stosb
  827.             $_else
  828.                 stosb
  829.             $_endif
  830.         $_until <cmp di, dx>, AE
  831.         mov        cx, offset DGROUP:c_len_ + NC
  832.         sub        cx, di
  833.         xor        al, al
  834.         rep        stosb
  835.         mov        ax, NC
  836.         pop        bp
  837.         mov        cx, 12
  838.         mov        di, offset DGROUP:c_table_
  839.         jmp        make_table_
  840.     $_endif
  841. read_c_len_    endp
  842.  
  843. ;    ushort decode_c_st1(void)
  844. decode_c    proc    near
  845. ;    not entry here
  846. decode_c_st1_2:
  847.     push    di
  848.     mov        al, 16
  849.     call    getbits_
  850.     dec        ax
  851.     mov        blocksize_, ax
  852.     mov        si, NT
  853.     mov        dl, TBIT
  854.     mov        cx, 3
  855.     call    read_pt_len_
  856.     call    read_c_len_
  857.     mov        si, NP
  858.     mov        dl, PBIT
  859.     mov        cx, -1
  860.     call    read_pt_len_
  861.     pop        di
  862.     jmp        decode_c_st1_3
  863. ;
  864. ;    entry here
  865. ;
  866. public    decode_c_st1_
  867. decode_c_st1_:
  868.     sub        blocksize_, 1
  869.     jc        decode_c_st1_2
  870. decode_c_st1_3:
  871.     mov        bx, bitbuf_
  872.     mov        cl, 4
  873.     shr        bx, cl
  874.     shl        bx, 1
  875.     mov        bx, c_table_[bx]
  876.     $_if    <cmp bx, NC>, B
  877. decode_c_st1_1:
  878.         push    bx
  879.         mov        al, c_len_[bx]
  880.         call    fillbuf_
  881.         pop        ax
  882.         ret
  883.     $_endif
  884.     mov        ax, bitbuf_
  885.     shl        al, cl
  886.     mov        si, offset decode_c_st1_1
  887.     mov        cx, NC
  888. tree0:
  889.     $_do
  890.         $_if <shl al, 1>, C
  891.             mov        bx, right_[bx]
  892.         $_else
  893.             mov        bx, left_[bx]
  894.         $_endif
  895. tree1:
  896.     $_until <cmp bx, cx>, B
  897.     jmp        si
  898. decode_c    endp
  899.  
  900. ;    ushort decode_p_st1(void)
  901. public    decode_p_st1_
  902. decode_p_st1_    proc    near
  903. ;---------------------------------------------------------------
  904. ;    ushort decode_p_st1(void)
  905. ;---------------------------------------------------------------
  906.     push    cx
  907.     xor        bh, bh
  908.     mov        bl, byte ptr bitbuf_ + 1
  909.     shl        bx, 1
  910.     mov        bx, pt_table_[bx]
  911.     $_if    <cmp bx, NP>, B
  912. decode_p_st1_1:
  913.         push    bx
  914.         mov        al, pt_len_[bx]
  915.         call    fillbuf_
  916.         pop        ax
  917.         $_if <cmp al, 1>, A
  918.             dec        ax
  919.             mov        cx, ax
  920.             call    getbits_
  921.             mov        bx, 1
  922.             shl        bx, cl
  923.             or        ax, bx
  924.         $_endif
  925.         pop        cx
  926.         ret
  927.     $_endif
  928.     mov        al, byte ptr bitbuf_
  929.     mov        si, offset decode_p_st1_1
  930.     mov        cx, NP
  931.     jmp        tree0
  932.  
  933. if 0
  934.     $_do
  935.         $_if <shl al, 1>, C
  936.             mov        bx, right_[bx]
  937.         $_else
  938.             mov        bx, left_[bx]
  939.         $_endif
  940.     $_until <cmp bx, NP>, B
  941.     jmp        decode_p_st1_1
  942. endif
  943. decode_p_st1_    endp
  944.  
  945.  
  946. ;---------------------------------------------------------------
  947. ;    void make_table(short nchar, uchar bitlen[],
  948. ;                             ax            bp
  949. ;                    short tablebits, ushort table[])
  950. ;                                 cx            di
  951. ;---------------------------------------------------------------
  952. _BSS    segment para public 'BSS'
  953. avail_mt        dw        1 dup (?)
  954. nchar            dw        1 dup (?)
  955. bitlen            dw        1 dup (?)
  956. tablebits        dw        1 dup (?)
  957. table            dw        1 dup (?)
  958. restbits        db        1 dup (?)
  959.  
  960. public    avail_mt
  961. public    nchar
  962. public    bitlen
  963. public    tablebits
  964. public    table
  965. public    restbits
  966. _BSS    ends
  967.  
  968.     public    make_table_
  969. make_table_    proc    near
  970.     mov        nchar, ax
  971.     shl        ax, 1
  972.     mov        avail_mt, ax
  973.     mov        tablebits, cx
  974.     mov        table, di
  975.     mov        al, 16
  976.     sub        al, cl
  977.     mov        restbits, al
  978.  
  979.     mov        ax, 1
  980.     shl        ax, cl
  981.     mov        cx, ax
  982.     xor        ax, ax
  983.     rep        stosw
  984.  
  985.     xor        si, si
  986.     mov        bx, 8000h
  987.     mov        dx, 1
  988.     $_do
  989.         mov        di, bp
  990.         mov        cx, nchar
  991.         $_do
  992.             mov        al, dl
  993.             repne    scasb
  994.             jne        mt1
  995.             mov        ax, di
  996.             sub        ax, bp
  997.             dec        ax
  998.             push    cx
  999.             push    di
  1000. ;            ; bx = weight
  1001. ;            ; si = code
  1002. ;            ; dx = len
  1003.             mov        cl, restbits
  1004.             mov        di, si
  1005.             shr        di, cl
  1006.             shl        di, 1
  1007.             add        di, table
  1008.             push    bx
  1009.             $_if <cmp dx, tablebits>, BE
  1010.                 shr        bx, cl
  1011.                 mov        cx, bx
  1012.                 rep        stosw
  1013.             $_else
  1014. ;        /* ìéé│ n é╠ tree é≡ì∞éΘ */
  1015. ;                ; di = taddr
  1016. ;                ; si = 
  1017. ;                ; cx = 
  1018. ;                ; ax = char
  1019.                 push    si
  1020.                 mov        cx, tablebits
  1021.                 shl        si, cl
  1022.                 neg        cx
  1023.                 add        cx, dx
  1024.                 $_do
  1025.                     $_if <cmp word ptr [di], 0>, E
  1026. ;                /* Ä}é¬é▄é╛ëäé╤é─éóé╚é»éΩé╬ì∞éΘ */
  1027.                         mov        bx, avail_mt
  1028.                         mov        right_[bx], 0
  1029.                         mov        left_[bx], 0
  1030.                         mov        [di], bx
  1031.                         add        avail_mt, 2
  1032.                     $_endif
  1033.                     mov        di, [di]
  1034.                     $_if <shl si, 1>, C
  1035.                         add        di, offset DGROUP:right_
  1036.                     $_else
  1037.                         add        di, offset DGROUP:left_
  1038.                     $_endif
  1039.                 $_until <LOOP>
  1040.                 mov        [di], ax
  1041.                 pop        si
  1042.             $_endif
  1043.             pop        bx
  1044.             pop        di
  1045.             pop        cx
  1046.             add        si, bx
  1047.             jc        mt2
  1048.         $_until <or cx, cx>, Z
  1049. mt1:
  1050.         inc        dx
  1051.         shr        bx, 1
  1052.     $_until , C
  1053. public mt2
  1054. mt2:
  1055.     ret
  1056. make_table_    endp
  1057.  
  1058. ;-----------------------------------------------
  1059. ;        ôⁿù═é⌐éτéÄârâbâgé≡ô╛éΘ
  1060. ;-----------------------------------------------
  1061. ;
  1062. ;ushort getbits(uchar n)
  1063. ;{
  1064.     public    getbits_
  1065. getbits_:        
  1066.     push    cx
  1067.     mov        cl, 16
  1068.     sub        cl, al
  1069.     push    bitbuf_
  1070.     call    fillbuf_
  1071.     pop        ax
  1072.     shr        ax, cl
  1073.     pop        cx
  1074.     ret
  1075.  
  1076. ;
  1077. ;void fillbuf(uchar n)  /* Shift bitbuf n bits left, read n bits */
  1078. ;{
  1079.  
  1080.     public    fillbuf_
  1081. fillbuf_:
  1082.     push    cx
  1083.     push    dx
  1084.     mov        ch, al
  1085.     mov        cl, bitcount_
  1086.     mov        dx, bitbuf_
  1087.     mov        al, subbitbuf_
  1088.     $_if <cmp ch, cl>, A
  1089.         sub        ch, cl
  1090.         shl        dx, cl
  1091.         rol        al, cl
  1092.         add        dl, al
  1093.         mov        cl, 8
  1094. fb1:
  1095.         call    getc
  1096.         $_if <cmp ch, cl>, A
  1097.             sub        ch, cl
  1098.             mov        dh, dl
  1099.             mov        dl, al
  1100.             jmp        fb1
  1101.         $_endif
  1102.     $_endif
  1103.     sub        cl, ch
  1104.     mov        bitcount_, cl
  1105.     mov        cl, ch
  1106.     xor        ah, ah
  1107.     shl        dx, cl
  1108.     shl        ax, cl
  1109.     add        dl, ah
  1110.     mov        bitbuf_, dx
  1111.     mov        subbitbuf_, al
  1112.     pop        dx
  1113.     pop        cx
  1114.     ret
  1115.  
  1116.         public    #endofshort
  1117. #endofshort:
  1118.  
  1119.         public    @autoexec
  1120. @autoexec:
  1121.         $_if <cmp cs:autoflg, 0dh>, E
  1122.             push    cs
  1123.             pop        es
  1124.             mov        bx, (offset resident - top + 100h + 15) / 16
  1125.             mov        ah, 4ah
  1126.             int        21h
  1127.             push    cs
  1128.             pop        ds
  1129.             mov        si, offset auto
  1130.             int        2eh                        ; execute
  1131.         $_endif
  1132.         jmp        #autoexec
  1133.  
  1134. resident:
  1135.  
  1136. ;-----------------------------------------------
  1137. ;        Get options
  1138. ;-----------------------------------------------
  1139.         public    @getopt
  1140. @getopt:
  1141.         mov        ax, 3700h
  1142.         int        21h                                ; get switch char
  1143.         mov        si, cmdline
  1144.         mov        es:swchar, dl
  1145.  
  1146.         mov        es:fnnext, offset DGROUP:pathname
  1147.         $_do
  1148.             lodsb
  1149.             $_if <cmp al, ' '>, A
  1150.                 $_if <cmp al, es:swchar>, E, OR
  1151.                 $_c     <cmp al, '-'>, E
  1152. lp0:
  1153.                     lodsb
  1154.                     cmp        al, ' '
  1155.                     jbe        lp1
  1156.                     or        al, 20h
  1157.                     $_switch
  1158.                     $_case <cmp al, '!'>, E
  1159.                         shl        cs:autoflg, 1
  1160.                     $_case <cmp al, 'x'>, E
  1161.                         inc        cs:extend
  1162.                     $_case <cmp al, 'a'>, E
  1163.                         inc        cs:attrib
  1164.                     $_default
  1165.                         cmp        al, 'e'
  1166.                         jne        lp0
  1167.                         lodsb
  1168.                     $_endswitch
  1169.                 $_endif
  1170.                 dec        si
  1171.                 mov        di, offset DGROUP:pathname
  1172.                 push    si
  1173.                 call    convert
  1174.                 pop        si
  1175.                 push    ax
  1176.                 mov        al, '/'
  1177.                 call    trans
  1178.                 mov        al, '/'
  1179.                 $_if <cmp ah, al>, NE, AND
  1180.                 $_c  <cmp ah, ':'>, NE
  1181.                     stosb
  1182.                 $_endif
  1183.                 mov        es:fnnext, di
  1184.                 pop        ax
  1185. lp1:
  1186.             $_endif
  1187.         $_until <cmp al, 0dh>, E
  1188.         ret
  1189.  
  1190.         public    @extended
  1191. @extended:
  1192.             mov        si, dx
  1193.             mov        di, offset auto + 1        ; !.BAT ?
  1194.             cmp        cl, 5
  1195.             jne        mn5
  1196.             push    es
  1197.             push    cs
  1198.             pop        es
  1199.             xor        ch, ch
  1200.             rep        cmpsb
  1201.             pop        es
  1202.             je        mn2
  1203.  
  1204. ; -x switch ----------------------------
  1205. mn5:
  1206.             mov        si, dx
  1207.             mov        cx, si
  1208.             call    convert
  1209.             $_if <cmp cs:extend, 0>, E
  1210.                 mov        dx, cx            ; last delim
  1211.             $_endif
  1212.  
  1213. ; -eDIRECTORY --------------------------
  1214.             mov        si, dx
  1215.             mov        al, [si]
  1216.             $_if <cmp al, '/'>, NE
  1217.                 mov        di, fnnext
  1218.                 call    trans
  1219.                 mov        bx, di
  1220.                 mov        dx, offset DGROUP:pathname
  1221.             $_else
  1222.                 mov        ax, word ptr DGROUP:pathname
  1223.                 $_if <cmp ah, ':'>, E
  1224.                     dec        dx
  1225.                     dec        dx
  1226.                     mov        di, dx
  1227.                     mov        [di], ax    ; brakes FnLen and
  1228.                 $_endif                    ;    upper byte of FAttr
  1229.             $_endif
  1230.  
  1231. ; Make Directories ---------------------
  1232.             mov        si, dx
  1233.             $_do
  1234.                 lodsb
  1235.                 $_if <cmp al, '/'>, E
  1236.                     mov        byte ptr [si - 1], 0
  1237.                     mov        ah, 39h ; make dir
  1238.                     int        21h
  1239.                     mov        byte ptr [si - 1], '/'
  1240.                 $_endif
  1241.             $_until <cmp si, bx>, AE
  1242.  
  1243.             mov        fnptr, dx
  1244.             mov        cx, 1
  1245. mn2:
  1246.             ret
  1247.  
  1248. ; Set File Attributes ------------------
  1249.         public    @setattr
  1250. @setattr:
  1251.         $_if <cmp attrib, 0>, NE
  1252.             mov        dx, si
  1253.             mov        cl, byte ptr DGROUP:cpyhdr.FAttr
  1254.             xor        ch, ch
  1255.             mov        ax, 4301h
  1256.             int        21h                ; Set File Attributes
  1257.         $_endif
  1258.         ret
  1259.  
  1260. ;-----------------------------------------------
  1261. ;        convert '\' to '/' & terminater
  1262. ;-----------------------------------------------
  1263. conv    proc    near
  1264.         $_do
  1265.             $_if <cmp al, '\'>, E, OR
  1266.             $_c  <cmp al, '/'>, E
  1267.                 mov        byte ptr -1[si], '/'
  1268.                 mov        cx, si
  1269.             $_endif
  1270. ; is kanji ---------------------
  1271.             and        al, 0e0h
  1272.             shl        al, 1
  1273.             $_if , C, AND
  1274.             $_c  , PE
  1275.                 inc        si
  1276.             $_endif
  1277. ; ------------------------------
  1278. convert:
  1279.             lodsb
  1280.         $_until <cmp al, ' '>, BE
  1281.         dec        si
  1282.         mov        byte ptr [si], 0
  1283.         ret
  1284. conv    endp
  1285.  
  1286. ;-----------------------------------------------
  1287. ;        transfer string
  1288. ;-----------------------------------------------
  1289. trans    proc    near
  1290.         $_do
  1291.             mov        ah, al
  1292.             lodsb
  1293.             stosb
  1294.         $_until <or al, al>, E
  1295.         dec        di
  1296.         ret
  1297. trans    endp
  1298.  
  1299.         public    #endofcode
  1300. #endofcode:
  1301. _TEXT    ends
  1302.         end        top
  1303.